# encoding  :  utf-8 _*_
# @author   :  朱清闯
# @software :  PyCharm
# time      :  2022/3/27 23:58

import jwt
from rest_framework.exceptions import AuthenticationFailed
from rest_framework_jwt.authentication import jwt_decode_handler
from rest_framework_jwt.authentication import get_authorization_header
from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication
from django.contrib.auth.backends import ModelBackend
from account.models import User
import re


class JSONWebTokenAuthentication(BaseJSONWebTokenAuthentication):
    def authenticate(self, request):
        # 采用drf获取token的手段 - HTTP_AUTHORIZATION - Authorization
        token = get_authorization_header(request)
        if not token:
            raise AuthenticationFailed('Authorization 字段是必须的')
        # 可以添加反扒措施：原功能是token有前缀

        # drf-jwt认证校验算法
        try:
            payload = jwt_decode_handler(token)
        except jwt.ExpiredSignature:
            raise AuthenticationFailed('签名过期')
        except jwt.InvalidTokenError:
            raise AuthenticationFailed('非法用户')
        user = self.authenticate_credentials(payload)
        # 将认证结果丢该drf
        return user, token


class JWTModelBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        """
        :param request:
        :param username: 前台传入的用户名
        :param password: 前台传入的密码
        :param kwargs:
        :return:
        """
        try:
            if re.match(r'^1[3-9]\d{9}$', username):
                user = User.objects.get(mobile=username)
            elif re.match(r'.*@.*', username):
                user = User.objects.get(email=username)
            else:
                user = User.objects.get(username=username)
        except User.DoesNotExist:
            return None  # 认证失败就返回None即可，jwt就无法删除token
        # 用户存在，密码校验通过，是活着的用户 is_active字段为1
        if user and user.check_password(password) and self.user_can_authenticate(user):
            return user  # 认证通过返回用户，交给jwt生成token

